package edu.xidian.cnmano.k8sclient;

import io.kubernetes.client.informer.SharedIndexInformer;
import io.kubernetes.client.informer.SharedInformerFactory;
import io.kubernetes.client.openapi.apis.AppsV1Api;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.*;
import io.kubernetes.client.util.CallGeneratorParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @author zhr k8s的Informer主要用于节点信息的监控，api-server会通过informer的机制通知客户端有关于集群的资源、控制器的
 * 变化，从而避免客户端为了实时获取集群信息而不断轮询，导致api-server压力过大
 * @date 2020/11/27-21:57
 */
@Slf4j
@Component
public class Informers {

    @Bean
    public SharedInformerFactory sharedInformerFactory() {
        return new SharedInformerFactory();
    }

    @Bean
    public SharedIndexInformer<V1Service> V1ServiceInformer(@Qualifier("coreWatchV1Api") CoreV1Api coreWatchV1Api, SharedInformerFactory factory){
        SharedIndexInformer<V1Service> serviceInformer =
                factory.sharedIndexInformerFor(
                        (CallGeneratorParams params) -> {
                            return coreWatchV1Api.listServiceForAllNamespacesCall(
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    params.resourceVersion,
                                    params.timeoutSeconds,
                                    params.watch,
                                    null
                            );
                        },
                        V1Service.class,
                        V1ServiceList.class
                );
        return serviceInformer;
    }

    @Bean
    public SharedIndexInformer<V1Pod> V1PodInformer(@Qualifier("coreWatchV1Api") CoreV1Api coreWatchV1Api, SharedInformerFactory factory) {
        SharedIndexInformer<V1Pod> podInformer =
                factory.sharedIndexInformerFor(
                        (CallGeneratorParams params) -> {
                            return coreWatchV1Api.listPodForAllNamespacesCall(
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    params.resourceVersion,
                                    params.timeoutSeconds,
                                    params.watch,
                                    null
                            );
                        },
                        V1Pod.class,
                        V1PodList.class
                );
        return podInformer;
    }

    @Bean
    public SharedIndexInformer<V1Node> V1NodeInformer(@Qualifier("coreWatchV1Api") CoreV1Api coreWatchV1Api, SharedInformerFactory factory) {
        SharedIndexInformer<V1Node> nodeInformer =
                factory.sharedIndexInformerFor(
                        (CallGeneratorParams params) -> {
                            return coreWatchV1Api.listNodeCall(
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    params.resourceVersion,
                                    params.timeoutSeconds,
                                    params.watch,
                                    null
                            );
                        },
                        V1Node.class,
                        V1NodeList.class
                );
        return nodeInformer;
    }

    @Bean
    public SharedIndexInformer<V1Deployment> V1DeploymentInformer(@Qualifier("appsV1WatchApi") AppsV1Api appsV1WatchApi, SharedInformerFactory factory) {
        SharedIndexInformer<V1Deployment> deploymentInformer =
                factory.sharedIndexInformerFor(
                        (CallGeneratorParams params) -> {
                            return appsV1WatchApi.listDeploymentForAllNamespacesCall(
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    params.resourceVersion,
                                    params.timeoutSeconds,
                                    params.watch,
                                    null
                            );
                        },
                        V1Deployment.class,
                        V1DeploymentList.class
                );
        return deploymentInformer;
    }
}
